package com.rh.number.config;

import com.rh.number.entity.UserinfoEntity;
import com.rh.number.filter.JwtAuthenticationFilter;
import com.rh.number.handler.JwtAuthenticationEntryPoint;
import com.rh.number.mapper.UserinfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;

import java.util.Arrays;
import java.util.Collections;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;
    private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    // 构造函数注入过滤器（避免字段注入循环）
    public SecurityConfig(@Lazy JwtAuthenticationFilter jwtFilter,
                          JwtAuthenticationEntryPoint entryPoint) {
        this.jwtAuthenticationFilter = jwtFilter;
        this.jwtAuthenticationEntryPoint = entryPoint;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 1. 启用并配置CORS
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))

                // 2. 禁用CSRF
                .csrf(csrf -> csrf.disable())

                // 3. 配置请求授权
                .authorizeHttpRequests(auth -> auth
                        // 放行预检请求和认证接口
                        .requestMatchers(
                                "/api/auth/**",
                                "/api/users/init",
                                "/error",// 建议放行错误端点
                                "/api/auth/validate"
                        ).permitAll()
                        // 显式放行所有OPTIONS请求
                        .requestMatchers(request ->
                                request.getMethod().equals("OPTIONS")).permitAll()
                        // 其他请求需要认证
                        .anyRequest().authenticated()
                )

                // 4. 配置会话管理
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )

                // 5. 配置异常处理
                .exceptionHandling(exceptions -> exceptions
                        .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                )

                // 6. 添加JWT过滤器
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    // 7. 配置CORS源
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList(
                "http://localhost:9090",
                "http://203.189.6.175:9090",
                "http://glxt.bjrhtd.com:9090"
        ));
        configuration.setAllowedMethods(Arrays.asList(
                "GET", "POST", "PUT", "DELETE", "OPTIONS"
        ));
        configuration.setAllowedHeaders(Collections.singletonList("*"));
        configuration.setExposedHeaders(Collections.singletonList("Authorization"));
        configuration.setAllowCredentials(true);
        configuration.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
    @Bean
    public UserDetailsService userDetailsService(UserinfoMapper userMapper) {
        return username -> {
            UserinfoEntity user = userMapper.selectByUsername(username);
            if (user == null) throw new UsernameNotFoundException("用户不存在");
            return user; // 直接返回 UserinfoEntity 实例
        };
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12); // 强度因子12
    }

}